package com.example.license.service.impl;

import com.example.license.LicenseUtils.CustomLicenseManager;
import com.example.license.entity.LicenseManagerHolder;
import com.example.license.entity.LicenseConstant;
import com.example.license.service.ILicenseService;
import com.example.license.service.IUserClientService;
import de.schlichtherle.license.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.prefs.Preferences;

/**
 * @author YangJian
 * @Description: 证书接口业务类
 * @createTime 2022年04月05日 16:40
 */
@Slf4j
@Service
public class LicenseServiceImpl implements ILicenseService {
    @Autowired
    private IUserClientService service;

    @Override
    public synchronized boolean install() throws Exception {
        log.info("客户端安装证书开始");
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        LicenseContent result = null;
        LicenseManager licenseManager = LicenseManagerHolder
                .getLicenseManager(initLicenseParams(), service);
        // 安装证书
            result = licenseManager.install(new File(LicenseConstant.LICPATH));
            log.info(MessageFormat.format("客户端证书安装成功，证书有效期：{0} - {1}",
                    format.format(result.getNotBefore()),
                    format.format(result.getNotAfter())));
        return true;
    }

    @Override
    public boolean verify() {
        /************** 证书使用者端执行 ******************/
        log.info("客户端验证证书开始");
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        LicenseContent result = null;
        LicenseManager licenseManager = LicenseManagerHolder
                .getLicenseManager(initLicenseParams(), service);
        // 验证证书
        try {
            result = licenseManager.verify();
            log.info(MessageFormat.format("客户端证书校验通过，证书有效期：{0} - {1}",
                    format.format(result.getNotBefore()),
                    format.format(result.getNotAfter())));
        } catch (Exception e) {
            this.log.error("证书无效:请核查服务器是否取得授权或重新申请证书!", e);
            return false;
        }
        return true;
    }

    @Override
    public Map<String, Object> getCertificateInfo() {
        Map<String, Object> map = new HashMap<>(3);
        SimpleDateFormat ds = new SimpleDateFormat("yyyy-MM-dd");
        //初始化父类参数
        CustomLicenseManager management = new CustomLicenseManager(initLicenseParams());
        try {
            //获取当前安装证书信息
            LicenseContent content = management.getCertificateInfo();
            map = (Map<String, Object>) content.getExtra();
            map.put("notBefore", ds.format(content.getNotBefore()));
            map.put("notAfter", ds.format(content.getNotAfter()));
        } catch (Exception e) {
            e.printStackTrace();
            log.info("未安装证书");
        }
        return map;
    }

    @Override
    public boolean unInstall() {
        CustomLicenseManager management = new CustomLicenseManager(initLicenseParams());
        try {
            management.uninstall();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }


    /**
     * @return de.schlichtherle.license.LicenseParam
     * @description: 返回验证证书需要的参数
     * @author YangJian
     * @date 2022/4/5 16:43
     */
    private static LicenseParam initLicenseParams() {
        Preferences preference = Preferences
                .userNodeForPackage(LicenseServiceImpl.class);
        CipherParam cipherParam = new DefaultCipherParam(LicenseConstant.STOREPWD);
        KeyStoreParam privateStoreParam = new DefaultKeyStoreParam(
                LicenseServiceImpl.class, LicenseConstant.PUBPATH, LicenseConstant.PUBLICALIAS, LicenseConstant.STOREPWD, null);
        LicenseParam licenseParams = new DefaultLicenseParam(LicenseConstant.SUBJECT,
                preference, privateStoreParam, cipherParam);
        return licenseParams;
    }
}
